#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
端口进程终止工具

这个脚本用于查找并终止占用指定端口的进程。
使用方法：python kill_port.py <端口号>
"""

import os
import sys
import subprocess
import platform
import signal
import re


def get_process_on_port(port):
    """
    获取占用指定端口的进程ID
    
    Args:
        port (int): 要查询的端口号
        
    Returns:
        int: 进程ID，如果没有找到则返回None
    """
    system = platform.system()
    
    if system == "Windows":
        # Windows系统使用netstat命令
        try:
            # 使用netstat命令查找占用端口的进程
            output = subprocess.check_output(f'netstat -ano | findstr :{port}', shell=True).decode('utf-8')
            if not output:
                return None
                
            # 提取PID
            pattern = r'.*:' + re.escape(str(port)) + r'\s+.*\s+(\d+)'
            matches = re.findall(pattern, output)
            
            if matches:
                return int(matches[0])
            return None
        except subprocess.CalledProcessError:
            return None
    else:
        # Linux/Mac系统使用lsof命令
        try:
            # 使用lsof命令查找占用端口的进程
            output = subprocess.check_output(f'lsof -i :{port} -t', shell=True).decode('utf-8')
            if output:
                return int(output.strip())
            return None
        except subprocess.CalledProcessError:
            return None


def kill_process(pid):
    """
    终止指定PID的进程
    
    Args:
        pid (int): 要终止的进程ID
        
    Returns:
        bool: 是否成功终止进程
    """
    system = platform.system()
    
    try:
        if system == "Windows":
            # Windows系统使用taskkill命令
            subprocess.check_call(f'taskkill /F /PID {pid}', shell=True)
        else:
            # Linux/Mac系统使用kill命令
            os.kill(pid, signal.SIGKILL)
        return True
    except (subprocess.CalledProcessError, OSError):
        return False


def main():
    """主函数"""
    # 检查命令行参数
    if len(sys.argv) != 2:
        print(f"使用方法: python {os.path.basename(__file__)} <端口号>")
        sys.exit(1)
    
    try:
        port = int(sys.argv[1])
    except ValueError:
        print("错误: 端口号必须是一个整数")
        sys.exit(1)
    
    # 检查端口号范围
    if port < 1 or port > 65535:
        print("错误: 端口号必须在1-65535之间")
        sys.exit(1)
    
    print(f"正在查找占用端口 {port} 的进程...")
    
    # 获取占用端口的进程ID
    pid = get_process_on_port(port)
    
    if pid is None:
        print(f"没有找到占用端口 {port} 的进程")
        sys.exit(0)
    
    print(f"找到占用端口 {port} 的进程，PID: {pid}")
    
    # 终止进程
    print(f"正在终止进程 {pid}...")
    if kill_process(pid):
        print(f"成功终止进程 {pid}")
    else:
        print(f"无法终止进程 {pid}，请尝试以管理员权限运行")
        sys.exit(1)


if __name__ == "__main__":
    main()